package org.cybzacg.encryption.enums;

/**
 * 加密算法枚举
 * 定义支持的具体加密算法
 * 
 * @author encryption team
 * @version 1.0
 */
public enum EncryptionAlgorithm {
    
    // 对称加密算法
    AES("AES", "Advanced Encryption Standard", EncryptionType.SYMMETRIC, 128, 256),
    DES("DES", "Data Encryption Standard", EncryptionType.SYMMETRIC, 56, 56),
    TRIPLE_DES("3DES", "Triple Data Encryption Standard", EncryptionType.SYMMETRIC, 168, 168),
    BLOWFISH("Blowfish", "Blowfish symmetric cipher", EncryptionType.SYMMETRIC, 32, 448),
    TWOFISH("Twofish", "Twofish symmetric cipher", EncryptionType.SYMMETRIC, 128, 256),
    RC4("RC4", "Rivest Cipher 4", EncryptionType.STREAM, 40, 2048),
    RC5("RC5", "Rivest Cipher 5", EncryptionType.SYMMETRIC, 0, 2040),
    RC6("RC6", "Rivest Cipher 6", EncryptionType.SYMMETRIC, 128, 256),
    IDEA("IDEA", "International Data Encryption Algorithm", EncryptionType.SYMMETRIC, 128, 128),
    CAMELLIA("Camellia", "Camellia symmetric cipher", EncryptionType.SYMMETRIC, 128, 256),
    SERPENT("Serpent", "Serpent symmetric cipher", EncryptionType.SYMMETRIC, 128, 256),
    SM4("SM4", "ShangMi 4 Block Cipher", EncryptionType.SYMMETRIC, 128, 128),
    
    // 非对称加密算法
    RSA("RSA", "Rivest-Shamir-Adleman", EncryptionType.ASYMMETRIC, 1024, 16384),
    DSA("DSA", "Digital Signature Algorithm", EncryptionType.ASYMMETRIC, 512, 3072),
    ECDSA("ECDSA", "Elliptic Curve Digital Signature Algorithm", EncryptionType.ASYMMETRIC, 160, 521),
    ECDH("ECDH", "Elliptic Curve Diffie-Hellman", EncryptionType.ASYMMETRIC, 160, 521),
    ECIES("ECIES", "Elliptic Curve Integrated Encryption Scheme", EncryptionType.ASYMMETRIC, 160, 521),
    ELGAMAL("ElGamal", "ElGamal encryption system", EncryptionType.ASYMMETRIC, 512, 4096),
    DIFFIE_HELLMAN("DH", "Diffie-Hellman key exchange", EncryptionType.ASYMMETRIC, 512, 4096),
    SM2("SM2", "ShangMi 2 Elliptic Curve Cryptography", EncryptionType.ASYMMETRIC, 256, 256),
    
    // 哈希算法
    MD5("MD5", "Message Digest 5", EncryptionType.HASH, 0, 0),
    SHA1("SHA-1", "Secure Hash Algorithm 1", EncryptionType.HASH, 0, 0),
    SHA256("SHA-256", "Secure Hash Algorithm 256", EncryptionType.HASH, 0, 0),
    SHA384("SHA-384", "Secure Hash Algorithm 384", EncryptionType.HASH, 0, 0),
    SHA512("SHA-512", "Secure Hash Algorithm 512", EncryptionType.HASH, 0, 0),
    SHA3_256("SHA3-256", "Secure Hash Algorithm 3-256", EncryptionType.HASH, 0, 0),
    SHA3_384("SHA3-384", "Secure Hash Algorithm 3-384", EncryptionType.HASH, 0, 0),
    SHA3_512("SHA3-512", "Secure Hash Algorithm 3-512", EncryptionType.HASH, 0, 0),
    RIPEMD160("RIPEMD-160", "RACE Integrity Primitives Evaluation Message Digest 160", EncryptionType.HASH, 0, 0),
    WHIRLPOOL("Whirlpool", "Whirlpool hash function", EncryptionType.HASH, 0, 0),
    
    // 混合算法
    AES_RSA("AES-RSA", "AES with RSA key wrapping", EncryptionType.HYBRID, 128, 256),
    AES_DH("AES-DH", "AES with Diffie-Hellman key exchange", EncryptionType.HYBRID, 128, 256);
    
    private final String name;
    private final String description;
    private final EncryptionType type;
    private final int minKeySize;
    private final int maxKeySize;
    
    EncryptionAlgorithm(String name, String description, EncryptionType type, int minKeySize, int maxKeySize) {
        this.name = name;
        this.description = description;
        this.type = type;
        this.minKeySize = minKeySize;
        this.maxKeySize = maxKeySize;
    }
    
    /**
     * 获取算法名称
     * 
     * @return 算法名称
     */
    public String getName() {
        return name;
    }
    
    /**
     * 获取算法描述
     * 
     * @return 算法描述
     */
    public String getDescription() {
        return description;
    }
    
    /**
     * 获取加密类型
     * 
     * @return 加密类型
     */
    public EncryptionType getType() {
        return type;
    }
    
    /**
     * 获取最小密钥长度（位）
     * 
     * @return 最小密钥长度
     */
    public int getMinKeySize() {
        return minKeySize;
    }
    
    /**
     * 获取最大密钥长度（位）
     * 
     * @return 最大密钥长度
     */
    public int getMaxKeySize() {
        return maxKeySize;
    }
    
    /**
     * 检查是否为对称加密算法
     * 
     * @return 是否为对称加密算法
     */
    public boolean isSymmetric() {
        return type.isSymmetric();
    }
    
    /**
     * 检查是否为非对称加密算法
     * 
     * @return 是否为非对称加密算法
     */
    public boolean isAsymmetric() {
        return type.isAsymmetric();
    }
    
    /**
     * 检查是否为哈希算法
     * 
     * @return 是否为哈希算法
     */
    public boolean isHash() {
        return type.isHash();
    }
    
    /**
     * 检查是否为混合算法
     * 
     * @return 是否为混合算法
     */
    public boolean isHybrid() {
        return type.isHybrid();
    }
    
    /**
     * 检查是否需要密钥对
     * 
     * @return 是否需要密钥对
     */
    public boolean requiresKeyPair() {
        return type.requiresKeyPair();
    }
    
    /**
     * 检查密钥长度是否有效
     * 
     * @param keySize 密钥长度（位）
     * @return 是否有效
     */
    public boolean isValidKeySize(int keySize) {
        return keySize >= minKeySize && keySize <= maxKeySize;
    }
    
    /**
     * 获取推荐密钥长度
     * 
     * @return 推荐密钥长度
     */
    public int getRecommendedKeySize() {
        switch (this) {
            case AES:
            case BLOWFISH:
            case TWOFISH:
            case CAMELLIA:
            case SERPENT:
            case AES_RSA:
            case AES_DH:
                return 256;
            case DES:
                return 56;
            case TRIPLE_DES:
                return 168;
            case IDEA:
                return 128;
            case RSA:
                return 2048;
            case DSA:
                return 2048;
            case ECDSA:
            case ECDH:
            case ECIES:
                return 256;
            case ELGAMAL:
            case DIFFIE_HELLMAN:
                return 2048;
            default:
                return minKeySize > 0 ? minKeySize : 256;
        }
    }
    
    /**
     * 根据名称查找算法
     * 
     * @param name 算法名称
     * @return 算法，如果未找到返回null
     */
    public static EncryptionAlgorithm fromName(String name) {
        if (name == null) {
            return null;
        }
        
        for (EncryptionAlgorithm algorithm : values()) {
            if (algorithm.getName().equalsIgnoreCase(name) || 
                algorithm.name().equalsIgnoreCase(name)) {
                return algorithm;
            }
        }
        return null;
    }
    
    /**
     * 根据加密类型获取所有算法
     * 
     * @param type 加密类型
     * @return 算法数组
     */
    public static EncryptionAlgorithm[] getByType(EncryptionType type) {
        return java.util.Arrays.stream(values())
                .filter(algorithm -> algorithm.getType() == type)
                .toArray(EncryptionAlgorithm[]::new);
    }
    
    @Override
    public String toString() {
        return name + " (" + description + ")";
    }
}
